﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using Caliburn.Micro;
using PocketBook.Model;
using PocketBook.Properties;
using PocketBook.Tasks;
using PocketBook.ViewModels.Events;

namespace PocketBook.ViewModels
{
    [Export(typeof(IBookDesigner)), PartCreationPolicy(CreationPolicy.NonShared)]
    public class BookEditorViewModel : PropertyChangedBase, IBookDesigner, IHandle<NewDesignSelected>
    {
        private readonly List<PageSiteViewModel> _layout = new List<PageSiteViewModel>();
        private PageSiteViewModel _selectedItem;

        [ImportingConstructor]
        public BookEditorViewModel(IEventAggregator events)
        {
            Events = events;
            Events.Subscribe(this);

            foreach (var site in Enumerable.Range(0, Book.TotalPages).Select(n => new PageSiteViewModel(LabelFromIndex(n))))
            {
                _layout.Add(site);
                site.SiteContentChanged += OnSiteContentChanged;
            }

            Book = new Book();
        }

        public Book Book
        {
            get { return new Book(_layout.Select(site => site.Design)); }
            set
            {
                for (var i = 0; i < _layout.Count; ++i)
                    _layout[i].Design = value[i];

                NotifyOfPropertyChange(() => Layout);
                SelectedItem = _layout.First();
            }
        }

        public IEnumerable<object> Layout
        {
            get { return _layout; }
        }

        public PageSiteViewModel SelectedItem
        {
            get { return _selectedItem; }

            set
            {
                if (value == SelectedItem) return;

                _selectedItem = value;

                NotifyOfPropertyChange(() => SelectedItem);
                if (Events != null) Events.Publish(new ActiveDesignChanged(SelectedItem.Design));
            }
        }

        public IEnumerable<IResult> MoveDesign(PageSiteViewModel page)
        {
            var select = Show.Dialog<SelectPageViewModel>().With(dialog =>
            {
                dialog.DisplayName = Resources.Caption_MoveTo;
                dialog.Prompt = Resources.Prompt_MoveTo;
                dialog.PageList = _layout.Where(site => site != page);
            });

            yield return select;

            page.SwapDesignWith(select.Dialog.SelectedPage);
        }

        private IEventAggregator Events { get; set; }

        public void Handle(NewDesignSelected message)
        {
            if (SelectedItem != null)
                SelectedItem.Design = message.NewDesign;
        }

        private void OnSiteContentChanged(object sender, EventArgs e)
        {
            if (Events != null && sender == SelectedItem)
                Events.Publish(new ActiveDesignChanged(SelectedItem.Design));
        }

        private static string LabelFromIndex(int n)
        {
            return n == 0 ? "Front" : n == 1 ? "Back" : (n - 1).ToString();
        }

    }
}